import { JSONSchemaType } from "ajv";
import { IMiddleware } from "koa-router";

import { Article } from "../model";
import { ArticleStatus } from "../model/article";
import { validateBody, validateQuery } from "../middleware/validate";
import { pageValidator, objectIdValidator } from "./base";
import { ajv } from "../util/ajv";

interface GetArticles {
  current: number;
  limit: number;
  title?: string;
  status?: number;
  sort?: string;
  userId?: string;
}

interface UpdateArticleStatus {
  status: number;
}

const getArticlesSchema: JSONSchemaType<GetArticles> = {
  type: "object",
  properties: {
    current: {
      type: "number"
    },
    limit: {
      type: "number"
    },
    title: {
      type: "string",
      nullable: true,
      isNotEmpty: true
    },
    status: {
      type: "integer",
      nullable: true,
      enum: Object.values(ArticleStatus) as number[]
    },
    sort: {
      type: "string",
      nullable: true,
      enum: ["1", "-1"]
    },
    userId: {
      type: "string",
      nullable: true,
      isValidObjectId: true
    }
  },
  required: ["current", "limit"]
};
ajv.addSchema(getArticlesSchema, "getArticles");

const updateArticleStatusSchema: JSONSchemaType<UpdateArticleStatus> = {
  type: "object",
  properties: {
    status: {
      type: "integer",
      enum: Object.values(ArticleStatus) as number[]
    }
  },
  required: ["status"]
};
ajv.addSchema(updateArticleStatusSchema, "updateArticleStatus");

// Article ObjectId 校验
export const articleIdValidator: IMiddleware[] = [
  ...objectIdValidator(Article)
];

// 获取所有文章
export const getArticlesValidator: IMiddleware[] = [
  validateQuery("getArticles"),
  async (ctx, next) => {
    // 1. 获取 query 参数
    const status = ctx.query.status as any as ArticleStatus;
    const title = ctx.query.title as string;
    const userId = ctx.query.userId as string;

    // 2. 连接数据库获取 articles
    const query = Article.countDocuments({});

    // 2.1 根据参数筛选数据
    if (title) query.where("title").regex(title);
    if (status) query.where("status").equals(status);
    if (userId) query.where("author").equals(userId);
    const total = await query;
    ctx.state.total = total;
    await next();
  },
  pageValidator()
];

// 更新文章状态
export const updateArticleStatusValidator: IMiddleware[] = [
  validateBody("updateArticleStatus")
];
